//自定义方法
import XEUtils from 'xe-utils'
import {_t} from "vxe-table";

export default {

  /**
   * 通过行数据获取父行
   * @param _table
   * @param row
   * @returns {unknown}
   */
  getParentRow: function (_table,row) {
    const matchObj = this.getRowObj(_table,row);
    if (matchObj) {
      return matchObj.parent;
    }
  },

  /**
   * 获取行数据对应对象
   * @param _table
   * @param row
   */
  getRowObj:function(_table,row){
    const {removeList, fullTreeData, treeOpts } = _table;
    const matchObj = XEUtils.findTree(fullTreeData, item => item === row, treeOpts);
    return matchObj;
  },


  /**
   * 为父节点一层层都勾选上
   * @param _table
   * @param row
   */
  getParentCheck(_table,row){
    if(row!=null){
       let parent = this.getParentRow(_table,row);
       if(parent!=null){
         parent.indeterminate=true;
         this.getParentCheck(_table,parent);
       }
    }
  },





  /**
   * 按指定层级展开树
   */
  openTreeLv:function(_table,lv){
      _table.clearTreeExpand();
    this._openTreeLv(_table, _table.data, lv);
  },

  _openTreeLv:function(_table,rows,countdown){
    if (countdown == 0) return;
    if (rows != null && rows.length > 0) {
      for (let i = 0; i < rows.length; i++) {
        _table.setTreeExpansion(rows[i], true);
        if (countdown > 0) {
          if (rows[i]["children"] != null) {
            this._openTreeLv(_table, rows[i]["children"], countdown - 1);
          }
        }
      }
    }
  },



  /**
   * 插入
   * @param _table
   * @param row
   * @param item
   */
  insert2:function (_table,row,item) {
    let newitem = Object.assign(item,{checked:false,indeterminate:false});
    return new Promise(function(resolve, reject){
      _table.insertAt(newitem,row).then(()=>{
        resolve({row:newitem});
      });

    })

  },

  insert:function (_table,row,item) {
    const { fullTreeData, treeTableData, treeOpts } = _table;
    let newitem = Object.assign(item,{checked:false,indeterminate:false, _X_LOADED: false, _X_EXPAND: false, _X_INSERT: true,  _X_LEVEL:row._X_LEVEL});
    const matchObj = XEUtils.findTree(fullTreeData, item => item === row, treeOpts);

    if (!matchObj || matchObj.index === -1) {
      return null;
    }

    const { items, index, nodes } = matchObj
    const rowIndex = treeTableData.indexOf(row)

    return new Promise(function(resolve, reject){
      treeTableData.splice(rowIndex, 0, newitem);
      items.splice(rowIndex, 0, newitem);
      if(matchObj.parent==null){//如果是顶层，则需要
        let ind =  _table.data.indexOf(row);
        _table.data.splice(ind, 0, newitem);
      }
      _table._loadTreeData(treeTableData);
      resolve({row:newitem});
    })

  },

  /**
   * 追加
   * @param _table
   * @param row
   * @param item
   * @returns {null|Promise<{row: *}>}
   */
  append:function (_table,row,item) {
    const { fullTreeData, treeTableData, treeOpts } = _table;
    let newitem = Object.assign(item,{checked:false,indeterminate:false, _X_LOADED: false, _X_EXPAND: false, _X_INSERT: true,  _X_LEVEL:row._X_LEVEL});
    const matchObj = XEUtils.findTree(fullTreeData, item => item === row, treeOpts);

    if (!matchObj || matchObj.index === -1) {
      return null;
    }

    const { items, index, nodes } = matchObj
    const rowIndex = treeTableData.indexOf(row)

    return new Promise(function(resolve, reject){
      if (rowIndex > -1) {
        let _ind = treeTableData.length;
        for (let i = rowIndex+1; i < treeTableData.length; i++) {
          if(treeTableData[i]._X_LEVEL<=row._X_LEVEL){
            _ind = i;
            break;
          }
        }
        treeTableData.splice(_ind, 0, newitem)
      }
      items.splice(index+1, 0, newitem);
      if(matchObj.parent==null){//如果是顶层，则需要
        let ind =  _table.data.indexOf(row);
        _table.data.splice(ind+1, 0, newitem);
      }
      _table._loadTreeData(treeTableData);
      resolve({row:newitem});
    })
  },
  addFirst:function(_table,item){


  },




  /**
   * 插入子项，插入在最后一行
   * @param _table
   * @param item
   * @param row
   */
  appendChild:function (_table,row,item) {
    if(row==null)return;
    if(!row._X_EXPAND){
      _table.setTreeExpand(row,true);
    }

    return new Promise(function(resolve, reject){
      const { fullTreeData, treeTableData, treeOpts } = _table;
      let newitem = Object.assign(item,{ _X_LOADED: false, _X_EXPAND: false, _X_INSERT: true,  _X_LEVEL: row._X_LEVEL+1});
      let rowIndex = -1;
      let childRows = row[treeOpts.children];
      if(childRows==null||childRows.length==0){//没有子项的使用展开功能刷新
        childRows = [newitem];
        row[treeOpts.children]=childRows;
        _table.setTreeExpand(row,true);
        resolve({row:newitem});
      }else{
        let _bind =  treeTableData.indexOf(row);
        let _ind = treeTableData.length;
        for (let i = _bind+1; i < treeTableData.length; i++) {
          if(treeTableData[i]._X_LEVEL<=row._X_LEVEL){
            _ind = i;
            break;
          }
        }
        treeTableData.splice(_ind, 0, newitem);
        childRows.push(newitem);
        _table._loadTreeData(treeTableData);
        resolve({row:newitem});
      }
    })

  },

  /**
   * 删除行数据
   * @param _table
   * @param rows
   */
  remove:function (_table,rows) {
   // let allrows = this.getChildrenRow(_table,rows);
    if (!XEUtils.isArray(rows)) {
      rows = [rows]
    }
    _table.remove(rows);

    // let ids = [];
    // rows.forEach(item=>{
    //   ids.push(item.id)
    // })
    //
    // _table.data = XEUtils.searchTree(_table.data,item=>{
    //   if(ids.indexOf(item.id)>-1){
    //     return false;
    //   }
    //   return true;
    // });
    // _table.removeList=[];//真删除

  },


  allRowCallFunc(rows,callitem){
    if(rows==null)return;
    for (let i = 0; i < rows.length; i++) {
      callitem(rows[i])
      if(rows[i].children!=null){
        this.allRowCallFunc(rows[i].children,callitem);
      }
    }
  },


  /**
   * 获取所有的子级row,包含自己
   * @param _table
   * @param row
   * @returns {*}
   */
  getChildrenRow(_table,rows){
    let allrows = [];
    if (!XEUtils.isArray(rows)) {
      rows = [rows]
    }
    for (let i = 0; i < rows.length; i++) {
      this._getChildrenRow(_table,rows[i],allrows);
    }
    return allrows;
  },


  /**
   * 合并树 根据id与parentId合并树型
   * @param data
   */
  merge(data,id,parentId){
    if(data==null)return;
    id = id||'id';
    parentId = parentId||'parent_id';
    let allmp = {};
    data.forEach(item=>{
      allmp[item[id]]=item;
    })
    let root = [];
    data.forEach(item=>{
      let pid = item[parentId];
      let parentNode = allmp[pid];
      if(parentNode){
        if(parentNode.children){
          parentNode.children.push(item);
        }else{
          parentNode['children']=[item];
        }
      }else{
        root.push(item);
      }
    })
    return root;
  },


  /**
   * 刷新数据的序列值
   * @param outdata
   */
  refreshSeq(outdata){
    let seqlist =[];
    let idseqmp = {};
    this._refreshSeq(outdata,seqlist,idseqmp);
    return idseqmp;
  },

  _refreshSeq(rows,seqlist,idseqmp){
    if(rows==null)return;
    for (let i = 0; i < rows.length; i++) {
      seqlist.push("");
      rows[i]['_E_SEQ'] = seqlist.length;
      idseqmp[rows[i].id]=seqlist.length;
      if(rows[i].children!=null){
        this._refreshSeq(rows[i].children,seqlist,idseqmp);
      }
    }
  },

  checkType(data) { // 用来判断被拷贝对象数据类型的函数
    return Object.prototype.toString.call(data).slice(8, -1)
  },

  deepClone (target) { // 实现深度拷贝的函数
    let result, targetType = this.checkType(target)
    if (targetType === 'Object') { // 只有对象和数组才进行深度拷贝
      result = {}
    } else if (targetType === 'Array') {
      result = []
    } else {
      return target
    }
    for (let i in target) { // i为对象的key或数组的下标
      let value = target[i]
      let valueType = this.checkType(value)
      if (valueType === 'Object' || valueType === 'Array') {
        result[i] = this.deepClone(value) // 当拷贝的对象中还有数组或是对象时进行递归，克隆它们中的内容，直到递归完所有数组或对象为止
      } else {
        result[i] = value
      }
    }
    return result // 返回最终的结果
  },

  /**
   * 增加天数
   * @param dateStr
   * @param dayCount
   * @returns {string}
   */
  dateAddDays(dateStr,dayCount){
    dayCount = dayCount-1;
    let tempDate=new Date(dateStr.replace(/-/g,"/"));//把日期字符串转换成日期格式
    let resultDate=new Date((tempDate/1000+(86400*dayCount))*1000);//增加n天后的日期
    let MM= resultDate.getMonth()+1;
    let dd = resultDate.getDate();
    let resultDateStr=resultDate.getFullYear()+"-"+(MM<10?'0'+MM:MM)+"-"+(dd<10?'0'+dd:dd);//将日期转化为字符串格式
    return resultDateStr;
  },

  /**
   * 获取两个时间间隔天数
   * @param bdate
   * @param edate
   */
  getDiffDays(bdate,edate){
    let t1=new Date(bdate.replace(/-/g,"/"));
    let t2=new Date(edate.replace(/-/g,"/"));
    let days = parseInt((t2/1000-t1/1000)/86400+"");
    return days+1;
  },

  /**
   * 根据ID在树形中查找row
   */
  getRowbyId(outdata,val,field){
    field = field||'id';
    let plist = [];
    this._getRowbyId(outdata,val,field,plist);
    if(plist.length>0){
      return plist[0];
    }
  },

  _getRowbyId(rows,val,field,plist){
    for (let i = 0; i < rows.length; i++) {
      if(rows[i][field] == val){
         plist.push(rows[i]);
      }
      if(rows[i].children!=null){
         this._getRowbyId(rows[i].children,val,field,plist);
      }
    }
  },






  /**
   * 获取真实列表，除掉删除的行(注意，删除不是真删除，所以直接获取treeData等会有问题)
   */
  trueList:function(_table){
    let allrow = this.breakdown(_table.data);
    if(_table.removeList!=null&&_table.removeList.length>0){
      let dellist = this.breakdown(_table.removeList);
      if(allrow!=null&&allrow.length>0){
        allrow = allrow.filter(item=>{
            let fobj= dellist.find(ditem=>{return ditem.id==item.id});
            if(fobj!=null){
              return false;
            }
            return true;
        })
      }
    }
    return allrow;
  },


  /**
   * 分解树形结构为列表
   * @param data
   * @returns {[]}
   */
  breakdown(outdata){
    let ulist = [];
    let data = JSON.parse(JSON.stringify(outdata));
    this._breakdown(data,ulist);
    if(ulist.length>0){
      ulist.forEach(item=>{
        delete item.children;
        delete item._X_EXPAND;
        delete item._X_INSERT;
        delete item._X_LEVEL;
        delete item._X_LOADED;
      })
    }
    return ulist;
  },

  _breakdown(rows,ulist){
    if(rows==null)return;
    for (let i = 0; i < rows.length; i++) {
      ulist.push(rows[i]);
      if(rows[i].children!=null){
        this._breakdown(rows[i].children,ulist);
      }
    }
  },

  /**
   * 同样根据树形，取得列表结构，但不破坏里面的数据
   * @param treeData
   * @returns {[]}
   */
  getRowList(treeData){
    let ulist = [];
    let data = treeData;
    this._breakdown(data,ulist);
    return ulist;
  },


  /**
   * 把kzdata加入data，但根据ID，如果已经存在，则不管
   * @param data
   * @param kzdata
   * @param id
   */
  addNotRepeat(data,kzdata,id){
    id = id||'id';
    if(kzdata==null||kzdata.length==0)return data;
    let alldata = [...data];
    for (let i = 0; i < kzdata.length; i++) {
      let item = kzdata[i];
      let vflag = true;
      for (let j = 0; j < data.length; j++) {
        if(data[j][id]==item[id]){
          vflag = false;
          break;
        }
      }
      if(vflag){
        alldata.push(item)
      }
    }
    return alldata;
  },


  /**
   * 由根向子级递归
   * 注意，调用完成后，需要使用vue强制刷新  this.$forceUpdate()
   *
   */
  calTree:function(_table,field,type,allflag){
    allflag = allflag||false;//默认只更新倒数第二级,true则更新所有父级
    if(_table.data==null||_table.data.length==0)return;
    this._calTree(_table,_table.data,field,type,allflag);
  },

  _calTree:function(_table,rows,field,type,allflag){
    if(rows==null)return;
    for (let i = 0; i < rows.length; i++) {
         if(rows[i].children!=null&&rows[i].children.length>0){
           rows[i][field]=null;
           this._calTree(_table,rows[i].children,field,type,allflag);
         } else{
           this.calParent(_table,rows[i],field,type,allflag);
         }
    }
  },


  /**
   * 由子级向父级触发
   */
  calParent:function (_table,row,field,type,upper){
    upper = upper||false
    let rowobj = this.getRowObj(_table,row);
    if(rowobj==null||rowobj.parent==null)return;
    this.calPNode(_table,rowobj.parent,rowobj.items,field,type);

    if(upper){//继续往上层
      this.calParent(_table,rowobj.parent,field,type,upper);
    }

  },



  /**
   * 根据子节点，更新父节点数据
   */
  calPNode:function(_table,prow, crows,field,type){
    if(type=="max"){
      let maxval = "";
      crows.forEach(item=>{
        if(item[field]){
          if(maxval==""){
            maxval = item[field];
          }else if(item[field]>maxval){
            maxval = item[field];
          }
        }
      })
      if(maxval!=""){
        prow[field]=maxval;
      }
    }else if(type=="min"){
      let minval = "";
      crows.forEach(item=>{
        if(item[field]){
          if(minval==""){
            minval = item[field];
          }else if(item[field]<minval){
            minval = item[field];
          }
        }
      })
      if(minval!=""){
        prow[field]=minval;
      }
    }else if(type=="sum"){
      let sumval = 0;
      crows.forEach(item=>{
        if(item[field]){
          sumval +=  parseFloat(item[field]);
        }
      })
      if(sumval>0){
        prow[field]=sumval;
      }

    }else if(type=="sum-only-plan"){//计划使用的工程量合计，有特殊要求,合计的前题是所有子级都是最低一层
      let sumval = 0;
      let checkflag = false;
      let unit = null;
      crows.forEach(item=>{
        if(item.children&&item.children.length>0){
          checkflag = true;
          return;
        }
        if(item[field]){
          if(unit==null){
            unit = item['et_unit'];
          }else if(unit != item['et_unit']){
            checkflag = true;
            return;
          }
          sumval +=  parseFloat(item[field]);
        }
      })
      if(checkflag)return;
      if(sumval>0){
        prow[field]=sumval;
      }

    }

  },


  /**
   * 内部方法，递归使用
   * @param _table
   * @param row
   * @param arr
   * @returns {*}
   * @private
   */
  _getChildrenRow(_table,row,arr){
    const {treeOpts } = _table;
    if(row!=null){
      arr.push(row);
      let childRows = row[treeOpts.children];
      if(childRows!=null&&childRows.length>0){
        for (let i = 0; i < childRows.length ; i++) {
          this._getChildrenRow(_table,childRows[i],arr);
        }
      }
    }
    return arr;
  },


/**
   * 在数据源中查找数据
   * @param _table
   * @param projectName
   */
 getRowObjByName:function(_table,projectName){
  const {removeList, fullTreeData, treeOpts } = _table;
  const matchObj = XEUtils.findTree(fullTreeData, item => item.projectName.includes(projectName), treeOpts);
  return matchObj;
},

  /**
   * 由子级向父级触发 只适合分批分段数据
   */
   calParentPlan:function (_table,row,field,type,upper){
    upper = upper||false
    let rowobj = this.getRowObj(_table,row);
    if(rowobj==null||rowobj.parent==null)return;
    this.calPNodeData(_table,rowobj.parent,rowobj.items,field,type);

    if(upper){//继续往上层
      this.calParentPlan(_table,rowobj.parent,field,type,upper);
    }

  },

  /**
   * 根据子节点，更新父节点数据
   */
   calPNodeData:function(_table,prow, crows,field,type){
    if(type=="sum"){
      let sumval = 0;
      let id = field.replace("amount", "").replace("number", "");
      crows.forEach(item=>{
        if(item[field]){
          sumval +=  parseFloat(item[field]);
        }

      })
      if(sumval>0){
        prow[field]=sumval;
      }
      if(Number(prow[id+"amount"])&&Number(prow[id+"number"])){

        if(Number(prow[id+"number"]) == 0){
          prow[id+"price"] =0
        }else{
          prow[id+"price"] =(Number(prow[id+"amount"])/Number(prow[id+"number"])).toFixed(2)
        }
      }

    }

  },

}
